home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / mpegDecode / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-06  |  10.1 KB  |  481 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #include "video.h"
  22. #include "proto.h"
  23. #include <sys/types.h>
  24. #include <signal.h>
  25. #ifndef MIPS
  26. #include <netinet/in.h>
  27. #else
  28. #include <bsd/netinet/in.h>
  29. #endif
  30.  
  31. #include "util.h"
  32. #include "dither.h"
  33.  
  34. /* Define buffer length. */
  35.  
  36. #define BUF_LENGTH 80000
  37.  
  38. /* Function return type declarations */
  39. void usage();
  40.  
  41. /* External declaration of main decoding call. */
  42.  
  43. extern VidStream *mpegVidRsrc();
  44. extern VidStream *NewVidStream();
  45.  
  46. /* Declaration of global variable to hold dither info. */
  47.  
  48. int ditherType;
  49.  
  50. /* Global file pointer to incoming data. */
  51. FILE *input;
  52.  
  53. /* End of File flag. */
  54. static int EOF_flag = 0;
  55.  
  56. /* Loop flag. */
  57. int loopFlag = 0;
  58.  
  59. /* Shared memory flag. */
  60. int shmemFlag = 0;
  61.  
  62. /* Display image on screen? */
  63. int noDisplayFlag = 0;
  64.  
  65. /* Setjmp/Longjmp env. */
  66. jmp_buf env;
  67.  
  68.  
  69. /*
  70.  *--------------------------------------------------------------
  71.  *
  72.  * get_more_data --
  73.  *
  74.  *    Called by correct_underflow in bit parsing utilities to
  75.  *      read in more data.
  76.  *
  77.  * Results:
  78.  *    Input buffer updated, buffer length updated.
  79.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  80.  *
  81.  * Side effects:
  82.  *      None.
  83.  *
  84.  *--------------------------------------------------------------
  85.  */
  86.  
  87. int 
  88. get_more_data(buf_start, max_length, length_ptr, buf_ptr)
  89.      unsigned int *buf_start;
  90.      int max_length;
  91.      int *length_ptr;
  92.      unsigned int **buf_ptr;
  93. {
  94.   
  95.   int length, num_read, i, request;
  96.   unsigned char *buffer, *mark;
  97.   unsigned int *lmark;
  98.  
  99.   if (EOF_flag) return 0;
  100.  
  101.   length = *length_ptr;
  102.   buffer = (unsigned char *) *buf_ptr;
  103.  
  104.   if (length > 0) {
  105.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  106.     mark = ((unsigned char *) (buf_start + length));
  107.   }
  108.   else {
  109.     mark = (unsigned char *) buf_start;
  110.     length = 0;
  111.   }
  112.  
  113.   request = (max_length-length)*4;
  114.   
  115.   num_read = fread( mark, 1, request, input);
  116.  
  117.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  118.   {
  119.     int num_read_rounded;
  120.     unsigned char *index;
  121.  
  122.     num_read_rounded = 4*(num_read/4);
  123.  
  124.     /* this can happen only if num_read<request; i.e. end of file reached */
  125.     if( num_read_rounded < num_read )
  126.       { 
  127.      num_read_rounded = 4*( num_read/4+1 );
  128.      /* fill in with zeros */
  129.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  130.      /* advance to the next 4-byte boundary */
  131.      num_read = num_read_rounded;
  132.       }
  133.   }
  134.   
  135.   if   (num_read < 0) {
  136.     return -1;
  137.   }
  138.   else if (num_read == 0) {
  139.     *buf_ptr = buf_start;
  140.     
  141.     /* Make 32 bits after end equal to 0 and 32
  142.        bits after that equal to seq end code
  143.        in order to prevent messy data from infinite
  144.        recursion.
  145.     */
  146.  
  147.     *(buf_start + length) = 0x0;
  148.     *(buf_start + length+1) = SEQ_END_CODE;
  149.  
  150.     EOF_flag = 1;
  151.     return 0;
  152.   }
  153.  
  154.   lmark = (unsigned int *) mark;
  155.  
  156.   num_read = num_read/4;
  157.  
  158.   for (i=0; i<num_read; i++) {
  159.     *lmark = htonl(*lmark);
  160.     lmark++;
  161.   }
  162.  
  163.   *buf_ptr = buf_start;
  164.   *length_ptr = length + num_read;
  165.  
  166.   return 1;
  167. }
  168.  
  169. /*
  170.  *--------------------------------------------------------------
  171.  *
  172.  * int_handler --
  173.  *
  174.  *    Handles Cntl-C interupts..
  175.  *
  176.  * Results:
  177.  *    None.
  178.  *
  179.  * Side effects:
  180.  *    None.
  181.  *
  182.  *--------------------------------------------------------------
  183.  */
  184. //void
  185. int int_handler()
  186. {
  187.   if (curVidStream != NULL)
  188.     DestroyVidStream(curVidStream);
  189.   exit(1);
  190. }
  191.  
  192.  
  193. /*
  194.  *--------------------------------------------------------------
  195.  *
  196.  * main --
  197.  *
  198.  *    Parses command line, starts decoding and displaying.
  199.  *
  200.  * Results:
  201.  *    None.
  202.  *
  203.  * Side effects:
  204.  *    None.
  205.  *
  206.  *--------------------------------------------------------------
  207.  */
  208.  
  209. void
  210. main(argc, argv)
  211.      int argc;
  212.      char **argv;
  213. {
  214.  
  215.   char *name;
  216.   static VidStream *theStream;
  217.   int mark;
  218.   int i;
  219.  
  220.   mark = 1;
  221.   argc--;
  222.  
  223.   name = "";
  224.   input = stdin;
  225.   ditherType = FULL_COLOR_DITHER;
  226.   LUM_RANGE = 8;
  227.   CR_RANGE = CB_RANGE = 4;
  228.   noDisplayFlag = 0;
  229.  
  230. #ifdef SH_MEM
  231.   shmemFlag = 1;
  232. #endif
  233.  
  234.   while (argc) {
  235.     if (strcmp(argv[mark], "-nop") == 0) {
  236.       TogglePFlag();
  237.       argc--; mark++;
  238.     } else if (strcmp(argv[mark], "-nob") == 0) {
  239.       ToggleBFlag();
  240.       argc--; mark++;
  241.     } else if (strcmp(argv[mark], "-display") == 0) {
  242.       name = argv[++mark];
  243.       argc -= 2; mark++;
  244.     } else if (strcmp(argv[mark], "-dither") == 0) {
  245.       argc--; mark++;
  246.       if (argc < 1) {
  247.     perror("Must specify dither option after -dither flag");
  248.     usage(argv[0]);
  249.       }
  250.       if (strcmp(argv[mark], "gray") == 0) {
  251.     argc--; mark++;
  252.     ditherType = GRAY_DITHER;
  253.       } else if (strcmp(argv[mark], "color") == 0) {
  254.     argc--; mark++;
  255.     ditherType = FULL_COLOR_DITHER;
  256.       } else if (strcmp(argv[mark], "none") == 0) {
  257.     argc--; mark++;
  258.     ditherType = NO_DITHER;
  259.       } else if (strcmp(argv[mark], "mono") == 0) {
  260.     argc--; mark++;
  261.     ditherType = MONO_DITHER;
  262.       } else if (strcmp(argv[mark], "threshold") == 0) {
  263.     argc--; mark++;
  264.     ditherType = MONO_THRESHOLD;
  265.       } else {
  266.     perror("Illegal dither option.");
  267.     usage(argv[0]);
  268.       }
  269.     } 
  270.     else if (strcmp(argv[mark], "-eachstat") == 0) {
  271.       argc--; mark++;
  272. #ifdef ANALYSIS
  273.       showEachFlag = 1;
  274. #else
  275.       fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
  276.       exit(1);
  277. #endif
  278.     }
  279.     else if (strcmp(argv[mark], "-shmem_off") == 0) {
  280.       argc--; mark++;
  281.       shmemFlag = 0;
  282.     }
  283.     else if (strcmp(argv[mark], "-loop") == 0) {
  284.       argc--; mark++;
  285.       loopFlag = 1;
  286.     }
  287.     else if (strcmp(argv[mark], "-no_display") == 0) {
  288.       argc--; mark++;
  289.       noDisplayFlag = 1;
  290.     }
  291.     else if (strcmp(argv[mark], "-l_range") == 0) {
  292.       argc--; mark++;
  293.       LUM_RANGE = atoi(argv[mark]);
  294.       if (LUM_RANGE < 1) {
  295.     fprintf(stderr, "Illegal luminance range value: %d\n", LUM_RANGE);
  296.     exit(1);
  297.       }
  298.       argc--; mark++;
  299.     }
  300.     else if (strcmp(argv[mark], "-cr_range") == 0) {
  301.       argc--; mark++;
  302.       CR_RANGE = atoi(argv[mark]);
  303.       if (CR_RANGE < 1) {
  304.     fprintf(stderr, "Illegal cr range value: %d\n", CR_RANGE);
  305.     exit(1);
  306.       }
  307.       argc--; mark++;
  308.     }
  309.     else if (strcmp(argv[mark], "-cb_range") == 0) {
  310.       argc--; mark++;
  311.       CB_RANGE = atoi(argv[mark]);
  312.       if (CB_RANGE < 1) {
  313.     fprintf(stderr, "Illegal cb range value: %d\n", CB_RANGE);
  314.     exit(1);
  315.       }
  316.       argc--; mark++;
  317.     }
  318.     else if (argv[mark][0] == '-') {
  319.       fprintf(stderr, "Un-recognized flag %s\n",argv[mark]);
  320.       usage(argv[0]);
  321.     }
  322.     else {
  323.       input = fopen(argv[mark], "r");
  324.       if (input == NULL) {
  325.     fprintf(stderr, "Could not open file %s\n", argv[mark]);
  326.     usage(argv[0]);
  327.       }
  328.       argc--; mark++;
  329.     }
  330.   }
  331.  
  332.   lum_values = (int *) malloc(LUM_RANGE*sizeof(int));
  333.   cr_values = (int *) malloc(CR_RANGE*sizeof(int));
  334.   cb_values = (int *) malloc(CB_RANGE*sizeof(int));
  335.  
  336.   signal(SIGINT, int_handler);
  337.  
  338.   init_tables();
  339.   
  340.   switch (ditherType) {
  341.     
  342.   case GRAY_DITHER:
  343. //    InitGrayDisplay(name);
  344.     break;
  345.  
  346.   case FULL_COLOR_DITHER:
  347.     InitColorDither();
  348. //    InitColorDisplay(name);
  349.     break;
  350.  
  351.   case NO_DITHER:
  352.     shmemFlag = 0;
  353.     break;
  354.  
  355.   case MONO_DITHER:
  356.   case MONO_THRESHOLD:
  357. //    InitMonoDisplay(name);
  358.     break;
  359.  
  360.   }
  361.  
  362. #ifdef SH_MEM
  363.     if (shmemFlag && (display != NULL)) {
  364.       if (!XShmQueryExtension(display)) {
  365.     shmemFlag = 0;
  366.       }
  367.     }
  368. #endif
  369.  
  370.   if (setjmp(env) != 0) {
  371.  
  372.     DestroyVidStream(theStream);
  373.  
  374.     rewind(input);
  375.  
  376.     EOF_flag = 0;
  377.     curBits = 0;
  378.     bitOffset = 0;
  379.     bufLength = 0;
  380.     bitBuffer = NULL;
  381.     totNumFrames = 0;
  382. #ifdef ANALYSIS 
  383.     init_stats();
  384. #endif
  385.  
  386.   }
  387.  
  388.   theStream = NewVidStream(BUF_LENGTH);
  389.  
  390.  
  391.   mpegVidRsrc(0, theStream);
  392.  
  393.   i = 1;  
  394.  
  395. //  ResizeDisplay(curVidStream->h_size*i, curVidStream->v_size*i);
  396.  
  397.   realTimeStart = ReadSysClock();
  398.  
  399.   while (1) mpegVidRsrc(0, theStream);
  400. }
  401.  
  402.  
  403. /*
  404.  *--------------------------------------------------------------
  405.  *
  406.  * usage --
  407.  *
  408.  *    Print mpeg_play usage
  409.  *
  410.  * Results:
  411.  *    None.
  412.  *
  413.  * Side effects:
  414.  *    exits with a return value -1
  415.  *
  416.  *--------------------------------------------------------------
  417.  */
  418.  
  419. void
  420. usage(s)
  421. char *s;    /* program name */
  422. {
  423.     fprintf(stderr, "Usage:\n");
  424.     fprintf(stderr, "mpeg_play\n");
  425.     fprintf(stderr, "          [-nob]\n");
  426.     fprintf(stderr, "          [-nop]\n");
  427.     fprintf(stderr, "          [-dither {gray|color|none|mono|threshold}]\n");
  428.     fprintf(stderr, "          [-loop]\n");
  429.     fprintf(stderr, "          [-eachstat]\n");
  430.     fprintf(stderr, "          [-no_display]\n");
  431.     fprintf(stderr, "          file_name\n");
  432.     exit (-1);
  433. }
  434.  
  435.  
  436.  
  437. /*
  438.  *--------------------------------------------------------------
  439.  *
  440.  * DoDitherImage --
  441.  *
  442.  *    Called when image needs to be dithered. Selects correct
  443.  *      dither routine based on info in ditherType.
  444.  *
  445.  * Results:
  446.  *    None.
  447.  *
  448.  * Side effects:
  449.  *    None.
  450.  *
  451.  *--------------------------------------------------------------
  452.  */
  453.  
  454. void
  455. DoDitherImage(l, Cr, Cb, disp, h, w) 
  456. unsigned char *l, *Cr, *Cb, *disp;
  457. int h,w;
  458. {
  459.  
  460.   switch(ditherType) {
  461.   case FULL_COLOR_DITHER:
  462.     ColorDitherImage(l, Cr, Cb, disp, h, w);
  463.     break;
  464.  
  465.   case GRAY_DITHER:
  466.     GrayDitherImage(l, Cr, Cb, disp, h, w);
  467.     break;
  468.  
  469.   case NO_DITHER:
  470.     break;
  471.  
  472.   case MONO_DITHER:
  473.     MonoDitherImage(l, Cr, Cb, disp, h, w);
  474.     break;
  475.  
  476.   case MONO_THRESHOLD:
  477.     MonoThresholdImage(l, Cr, Cb, disp, h, w);
  478.     break;
  479.   }
  480. }
  481.